package cn.echogo.framework.activity;

import java.lang.ref.WeakReference;

import cn.echogo.framework.app.EGApplication;
import cn.echogo.framework.inter.Executable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

public abstract class ExecutableActivity extends EGActivity implements Executable<Bundle> {

	private static final int WHAT_EXECUTE_EXECEPTION = -4444;
	
	private InternalHandler internalHandler;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		application = (EGApplication) getApplication();

	}

	/**
	 * 获取要访问的URL
	 * 
	 * @param action 编码
	 * @return
	 */
	public abstract String getUrl(String action);

	public void execute(final int id, final Bundle bundle) {
		if (onPreExecute(id, bundle)) {
			if (internalHandler == null) {
				internalHandler = new InternalHandler(ExecutableActivity.this);
			}
			Runnable task = new Runnable() {
				@Override
				public void run() {
					try {
						Bundle result = onExecute(id, bundle);
						Message msg = internalHandler.obtainMessage(id);
						msg.setData(result);						
						msg.sendToTarget();
					} catch(Exception e) {
						Message msg = internalHandler.obtainMessage(WHAT_EXECUTE_EXECEPTION);
						msg.obj = e;			
						msg.arg1 = id;
						msg.setData(bundle);
						msg.sendToTarget();
					} 
				}
			};
			application.asyncTaskPool.submit(id, task);
		}
	}

	public void cancelExecute(int id) {
		application.asyncTaskPool.cancel(id);
	}

	public boolean onPreExecute(int id, Bundle bundle) {
		return true;
	};

	public abstract Bundle onExecute(int id, Bundle bundle) throws Exception;

	public abstract void onPostExecute(int id, Bundle bundle);
	
	public abstract void onException(int id, Bundle p, Exception e);

	private static class InternalHandler extends Handler {

		private WeakReference<ExecutableActivity> activityRef;

		public InternalHandler(ExecutableActivity activity) {
			activityRef = new WeakReference<ExecutableActivity>(activity);
		}

		public void handleMessage(Message msg) {
			if(msg.what == WHAT_EXECUTE_EXECEPTION) {
				int id = msg.arg1;
				Exception e = (Exception)msg.obj;
				Bundle bundle = msg.getData();
				activityRef.get().onException(id, bundle, e);
			} else {				
				int id = msg.what;
				Bundle result = msg.getData();
				activityRef.get().onPostExecute(id, result);
			}
		};
	};

}
